#pragma once
#include <compl.h>
#include <libapfsds.h>
typedef struct{
	struct{
		word_t volatile val;
		word_t volatile count;
	} ALIGN(HDEF_CACHE_LINE_BYTES);
}addcount_t;

static inline void *count_init(addcount_t *t)
{
	t->val = 1;
	t->count = 0;
	return t;
}

static inline word_t count_add(addcount_t *t)
{	
	word_t ret = t->val++;
#ifdef ADD_NOPNR	
	word_t nops = hash(ret) & (ADD_NOPNR - 1);
	word_t i = 0;
	do{
		NOP();
	} while(++i < nops);
#endif

	return ret;
}
static inline word_t count_multiply(addcount_t *t, word_t multi)
{
	word_t tmp = t->val;
	t->val = tmp * multi;
	if(t->val == 0) t->val = 1;
	return tmp;
}
MAY_UNUSED static word_t count_add_cb(APFSDS_ARGLIST)
{
	PARAM_USED(arg1, arg2, arg3);
	return count_add((addcount_t *)arg0);
}
MAY_UNUSED static word_t count_mul_cb(APFSDS_ARGLIST)
{
	PARAM_USED(arg2, arg3);
	if(arg0 != 0)
		count_multiply((addcount_t *)arg0,(word_t)arg1);
	return (++((addcount_t *)arg0)->count);
}